/*
 *  KTAIL.java
 * 
 *  Copyright (C) 2012-2013 Sylvain Lamprier, Tewfik Ziaidi, Lom Messan Hillah and Nicolas Baskiotis
 * 
 *  This file is part of CARE.
 * 
 *   CARE is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   CARE is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with CARE.  If not, see <http://www.gnu.org/licenses/>.
 */


package miners.KTail;

import java.io.File;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;

import miners.FSAminer;
//import fr.lip6.meta.traceGenerator.table.TraceGenResult;
//import fr.lip6.meta.traceGenerator.util.TraceIO;
import traces.Statement;
import traces.Trace;
import dataGenerator.*;
import fsa.EpsilonRemover;
import fsa.GenerateDOT;
import fsa.FSA;
import fsa.State;
import fsa.Transition;
import programs.*;
//import fr.lip6.meta.strategie.*;


/**
 * KTail miner
 * 
 * @author Sylvain Lamprier
 *
 */
public class KTail extends FSAminer{
	//private HashMap<String, Integer> state_indices;
	/*private HashMap<String, StateNode> states;
	private ArrayList<State> all_states;
	private ArrayList<State> initial_states;
	private ArrayList<State> final_states;*/
	//StatementComparaisonStrategy strategy;
	int horizon;
	/*public IncrementalKTail(int k){ //,StatementComparaisonStrategy st){
		//strategy=st;
		horizon=k;
		
	}*/
	
	public KTail(int k){
		//strategy=new StatementComparaisonClassLevel();
		horizon=k;
		
	}
	
	
	public String getName(){
		return("IncrementalKTail_k="+horizon); //+"_st="+strategy.toString());
	}
	
	@Override
	public FSA transform(ArrayList<Trace> traces) {
	
		StateNode root=new StateNode(); 
		HashSet<StateNode> all_states=new HashSet<StateNode>();
		HashSet<State> initial_states=new HashSet<State>();
		HashSet<State> final_states=new HashSet<State>();
		boolean vide=false;
		for(Trace t:traces){
			int size=t.getSize();
			if (size==0){
				vide=true;
			}
			ArrayList<Statement> thorizon=new ArrayList<Statement>();
			for(int i=1;((i<=size) && (i<=horizon));i++){
				Statement st=t.getByIndex(i);
				thorizon.add(st);
			}
			StateNode last_node=root.getSetStateNode(new ArrayList<Statement>(thorizon));
			all_states.add(last_node);
			initial_states.add(last_node);
			for(int i=1;i<=size;i++){
				if (i<=(size-horizon)){
					Statement st=t.getByIndex(i+horizon);
					thorizon.add(st);
				}
				else{
					thorizon.add(new Statement());
				}
				Statement first=thorizon.remove(0);
				StateNode stnode=root.getSetStateNode(new ArrayList<Statement>(thorizon));
				all_states.add(last_node);
				if (i==size){
					   final_states.add(stnode);
					   all_states.add(stnode);
				}
				last_node.addTransition(first,stnode);
				last_node=stnode;
			}
				
		}
		
		FSA fsa=new FSA();
		State source=new State();
		fsa.addStates(new ArrayList<State>(all_states));
		fsa.setInitialState(source);
		fsa.setFinalStates(new ArrayList<State>(final_states));
		if (vide){
			fsa.addFinalState(source);
		}
		for(State s:initial_states){
			Transition tr=new Transition(source,new Statement(),s);
			fsa.addTransition(tr);
		}
		for(StateNode s:all_states){
			fsa.addTransitions(new ArrayList<Transition>(s.getTransitions()));
		}
		EpsilonRemover.removeEpsilon(fsa);
		return(fsa);
	}
	
	static void deleteRecursive(File f)  {
		if (f.exists()){
			if (f.isDirectory()){
			  File[] childs=f.listFiles();
			  int i=0;
			  for(i=0;i<childs.length;i++){
				  deleteRecursive(childs[i]);
			  }
			  
			}
			f.delete();
		 }
	}
	
	
	
	
	
	//private 
	
}
